/****************************************************************************

	COPYRIGHT(C) MAXSI SOFTWARE, JONAS 'SORTIE' TERMANSEN 2008, 2009, 2010

    This file is part of Maxsi Engine.

    Maxsi Engine is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    Maxsi Engine is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    GNU Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public License
    along with Maxsi Engine. If not, see <http://www.gnu.org/licenses/>.

	*/ #include "MaxsiEngineContributors.h" /*

	If you modify this file, please enter your name below and provide contact
	information in MaxsiEngineContributors.h. For more information please see
	MaxsiEngineContributors.h.
	
	Contributors to this file:

	- Jonas 'Sortie' Termansen
	- [your name here]

	MaxsiEngine.dll
	A linkable version of Maxsi Engine

	MaxsiFolder.cpp
	Functions for handling folders easier

****************************************************************************/

#include "MaxsiEngine.h"
#include <time.h>
#include <io.h>
#include <direct.h>

namespace MaxsiEngine
{
	FolderStructure::FolderStructure()
	{
		SubFolders	= 0;
		SubFiles	= 0;
		FolderName	= 0;
	}

	FolderStructure::~FolderStructure()
	{
		if ( FolderName ) { delete[] FolderName; }
		DeleteList	(SubFolders);
		DeleteList	(SubFiles);
	}

	int	FolderStructure::CreateFromFileList(List FileList)
	{
		size_t FileList_Size = GetListSize(FileList);
		size_t NumSubFiles = 0;
		for (char K = 0; K < 2; K++)
		{
			for (size_t I = 0; I < FileList_Size; I++)
			{
				char* FileName = (char*)GetListEntry(FileList,(unsigned int)I);
				if ( FindChar(FileName,'/',strlen(FileName)+1) == ULONG_MAX &&
					 FindChar(FileName,'\\',strlen(FileName)+1) == ULONG_MAX )
				{
					// Subfile
					if ( K )
					{
						SetListEntry(SubFiles,(unsigned int)NumSubFiles,FileName,strlen(FileName)+1);
					}
					NumSubFiles++;					
				}
			}
			if ( !K )
			{
				SubFiles = CreateList(NumSubFiles);
			}
		}
		return 1;
	}

	LINKCPP FolderStructure* GetFolderStructure(char* Path, bool SubFolders, bool SubFiles, char* OverrideFolderName)
	{
		FolderStructure*	Result			=	new FolderStructure;
		__finddata64_t		File;
		char*				SeekPath		=	BuildString(2,Path,"*");
		size_t				NumFolders		=	0;
		size_t				NumFiles		=	0;
		size_t				FolderNum		=	0;
		size_t				FileNum			=	0;
		intptr_t			FileHandle;

		if (OverrideFolderName)
		{
			Result->FolderName = BuildString(1,OverrideFolderName);			
		}
		else
		{
			Result->FolderName = BuildString(1,Path);
		}

		for (char K = 0; K<2; K++)
		{
			if ( (FileHandle = _findfirst64( SeekPath, &File)) != -1L )
			{
				do
				{
					if (File.attrib & _A_SUBDIR)
					{
						if ( SubFolders && strcmp(File.name,".") != 0	&& strcmp(File.name,"..") != 0)
						{
							if (K>0)
							{
								FolderNum++;
								if ( FolderNum > NumFolders )
								{
									// If this point is reached, a new folder has been created in the meantime
									// and no space are reserved for it. Just ignore it
								}
								else
								{
									char*	SubPath = BuildString(3,Path,File.name,"/");
									//char Before[100];
									//char After[100];

									//memcpy(Before,Result->SubFolders,100);

									FolderStructure* TMP = GetFolderStructure(SubPath,SubFolders,SubFiles,File.name);
									SetListEntry(Result->SubFolders,(unsigned int)FolderNum-1,(char*)TMP,0);			
									delete[] SubPath;

									//memcpy(After,Result->SubFolders,100);

									//FolderStructure* LOL = (FolderStructure*)GetListEntry(Result->SubFolders,(unsigned int)FolderNum-1);
								}
							}
							else
							{
								// Count the number of folders.
								NumFolders++;
							}
						}
					}
					else if ( SubFiles )
					{
						if (K>0)
						{
							FileNum++;
							if ( FileNum > NumFiles )
							{
								// If this point is reached, a new file has been created in the meantime
								// and no space are reserved for it. Just ignore it
							}
							else
							{
								SetListEntry(Result->SubFiles,(unsigned int)FileNum-1,File.name,strlen(File.name)+1);								
							}
						}
						else
						{
							// Count the number of folders.
							NumFiles++;
						}
					}
				}
				while ( _findnext64( FileHandle, &File ) == 0 );

				if ( K == 0 )
				{
					Result->SubFolders	= CreateList(NumFolders);
					Result->SubFiles	= CreateList(NumFiles);
				}

			}
			_findclose( FileHandle );
		}
		return Result;
	}

	bool	MKDir(char* Directory)
	{
		bool			Result		=	true;
		size_t			Len			=	strlen(Directory);

		for (size_t I = 0; I < Len; I++)
		{
			if (Directory[I] == '/' || Directory[I] == '\\')
			{
				char* TempDir = new char[I+2];
				memcpy(TempDir,Directory,I+1);
				memset(TempDir+I+1,0,1);
				_mkdir(TempDir);
				delete TempDir;
			}
		}
		return	Result;		
	}

	bool	FileNameCMP(char* File1, char* File2)
	{
		return (_stricmp(File1, File2) == 0);
	}

	bool CompareFilePaths(MESTR* File1, MESTR* File2)
	{
		// Todo: Expand this function to cover more cases!
		return (_stricmp(File1, File2) == 0);		
	}

	MESTR* RemoveFilePathExt(MESTR* FilePath)
	{
		if ( FilePath == NULL ) { return NULL; }

		size_t	LastDot		=	FindCharPrev(FilePath, '.', MESTRLEN(FilePath));
		size_t	LastFSlash	=	FindCharPrev(FilePath, '/', MESTRLEN(FilePath));
		size_t	LastBSlash	=	FindCharPrev(FilePath, '\\', MESTRLEN(FilePath));

		// No dots in this filepath!
		if ( LastDot == ULONG_MAX )
		{
			return BuildString(1, FilePath);
		}

		// No dots in the filename!
		if ( LastDot < LastFSlash && LastDot < LastBSlash )
		{
			return BuildString(1, FilePath);
		}

		// Simply cut the extension
		return SubString(0, LastDot, FilePath);
	}

}